package alocador.entidades;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;

import alocador.exceptions.DataInvalidaException;
import alocador.exceptions.EventoInvalidoException;

/**
 * O pacote entidades diz respeito as entidades do Sistema, ou seja, Evento e Horario
 * Essa classe que modela a Entidade EventoRepetitivo. Realiza todas operacoes relacionadas a um Evento Repetitivo
 */
public class EventoRepetitivo extends Evento {

	//atributo especifico de Evento Repetitivo
	private ArrayList<Horario> listaHorario;

	//contrutor de Evento Repetitivo
	public EventoRepetitivo(String id, String nome, String inicio, String fim,
			String area, String contato, int repeticoes)
			throws EventoInvalidoException, DataInvalidaException {

		super(id, nome, inicio, fim, area, contato, repeticoes);
		listaHorario = new ArrayList<Horario>();
		setRepeticoes(repeticoes);
		Horario horario = new Horario(inicio, fim);
		adicionaHorario(horario);
	}

	/**
	 * Retorna a lista contendo todos horarios de um evento
	 * @return 
	 * 		Lista de Horario de um evento
	 */
	@Override
	protected ArrayList<Horario> getHorariosDoEvento() {
		return this.listaHorario;
	}

	/**
	 * Retorna um horario da lista de horario a partir de um indice
	 * @param indice
	 * 		Indice da lista de horario
	 * @return
	 * 		Horario no indice da lista de horario
	 */
	public Horario getHorario(int indice) {
		return getHorariosDoEvento().get(indice);
	}

	/**
	 * Retorna Quantidade de Horarios de um Evento
	 * @return
	 * 		Quantidade de Horarios de um Evento
	 */
	@Override
	public int numDeHorarios() {
		return listaHorario.size();
	}

	/**
	 * Verifica se Evento contem determinado Horario
	 * @param data
	 *      Data a ser verificada
	 * @return 
	 * 		True, caso Evento contenha horario. False, caso contrario
	 * @throws DataInvalidaException
	 * 		Caso a data esteja em formato errado, 30/02, por exemplo
	 */
	@Override
	protected boolean contemHorario(String data) throws DataInvalidaException {
		for (int i = 0; i < getRepeticoes(); i++) {
			if (getHorariosDoEvento().get(i).contemHorario(data)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Adiciona um horario a lista de horarios
	 * @param horario
	 * 		Horario a ser adicionado na lista de horario
	 */
	private void adicionaHorario(Horario horario) {

		getHorariosDoEvento().add(horario);
		for (int i = 0; i < getRepeticoes(); i++) {
			Horario horarioRep = Horario.avancaSemana(getHorariosDoEvento()
					.get(i));
			getHorariosDoEvento().add(horarioRep);
		}

	}

	/**
	 * Itera sobre o(s) horario(s) de um Evento
	 * @return
	 * 		Iterator de um Horario
	 */
	@Override
	public Iterator<Horario> horarioIterator() {
		return new Iterator<Horario>() {
			int cursor = 0;

			@Override
			public boolean hasNext() {
				return cursor < numDeHorarios();
			}

			@Override
			public Horario next() {
				try {
					Horario next = getHorario(cursor);
					cursor++;
					return next;
				} catch (NoSuchElementException e) {
					throw new IllegalArgumentException("Evento nao existente");
				}

			}

			@Override
			public void remove() {
				getHorariosDoEvento().remove(cursor);

			}

		};
	}

	/**
	 * Retorna as informacoes de um Evento Repetitivo
	 * @return
	 * 	Informacoes de um Evento Repetitivo
	 */
	@Override
	public String toString() {

		String saida  = "";
		
		saida += "Nome: " + getNome() + "Area: " + getArea() + "Contato: " + getContato() + "Horario(s): ";
		
		//pega todos os horario de um evento
		for (int i = 0; i < numDeHorarios(); i++) {
			saida += "Data de Inicio: " + getHorario(i).getDataInicio() + "Data de Termino: " + getHorario(i).getDataFim() + ", ";
		}
		
		//Retirar a ultima virgula
		saida = saida.substring(0, saida.length()-1);
		
		return saida;
		
	}

}
